//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2021 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto/tree/main/CodeGenerator. DO NOT EDIT.

import Foundation
import SotoCore

extension ResourceGroups {
    // MARK: Enums

    public enum GroupConfigurationStatus: String, CustomStringConvertible, Codable {
        case updateComplete = "UPDATE_COMPLETE"
        case updateFailed = "UPDATE_FAILED"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum GroupFilterName: String, CustomStringConvertible, Codable {
        case configurationType = "configuration-type"
        case resourceType = "resource-type"
        public var description: String { return self.rawValue }
    }

    public enum QueryErrorCode: String, CustomStringConvertible, Codable {
        case cloudformationStackInactive = "CLOUDFORMATION_STACK_INACTIVE"
        case cloudformationStackNotExisting = "CLOUDFORMATION_STACK_NOT_EXISTING"
        public var description: String { return self.rawValue }
    }

    public enum QueryType: String, CustomStringConvertible, Codable {
        case cloudformationStack10 = "CLOUDFORMATION_STACK_1_0"
        case tagFilters10 = "TAG_FILTERS_1_0"
        public var description: String { return self.rawValue }
    }

    public enum ResourceFilterName: String, CustomStringConvertible, Codable {
        case resourceType = "resource-type"
        public var description: String { return self.rawValue }
    }

    public enum ResourceStatusValue: String, CustomStringConvertible, Codable {
        case pending = "PENDING"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct CreateGroupInput: AWSEncodableShape {
        /// A configuration associates the resource group with an AWS service and specifies how the service can interact with the resources in the group. A configuration is an array of GroupConfigurationItem elements. For details about the syntax of service configurations, see Service configurations for resource groups.  A resource group can contain either a Configuration or a ResourceQuery, but not both.
        public let configuration: [GroupConfigurationItem]?
        /// The description of the resource group. Descriptions can consist of letters, numbers, hyphens, underscores, periods, and spaces.
        public let description: String?
        /// The name of the group, which is the identifier of the group in other operations. You can't change the name of a resource group after you create it. A resource group name can consist of letters, numbers, hyphens, periods, and underscores. The name cannot start with AWS or aws; these are reserved. A resource group name must be unique within each AWS Region in your AWS account.
        public let name: String
        /// The resource query that determines which AWS resources are members of this group. For more information about resource queries, see Create a tag-based group in Resource Groups.   A resource group can contain either a ResourceQuery or a Configuration, but not both.
        public let resourceQuery: ResourceQuery?
        /// The tags to add to the group. A tag is key-value pair string.
        public let tags: [String: String]?

        public init(configuration: [GroupConfigurationItem]? = nil, description: String? = nil, name: String, resourceQuery: ResourceQuery? = nil, tags: [String: String]? = nil) {
            self.configuration = configuration
            self.description = description
            self.name = name
            self.resourceQuery = resourceQuery
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.configuration?.forEach {
                try $0.validate(name: "\(name).configuration[]")
            }
            try self.validate(self.configuration, name: "configuration", parent: name, max: 2)
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "[\\sa-zA-Z0-9_\\.-]*")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "[a-zA-Z0-9_\\.-]+")
            try self.resourceQuery?.validate(name: "\(name).resourceQuery")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 0)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case configuration = "Configuration"
            case description = "Description"
            case name = "Name"
            case resourceQuery = "ResourceQuery"
            case tags = "Tags"
        }
    }

    public struct CreateGroupOutput: AWSDecodableShape {
        /// The description of the resource group.
        public let group: Group?
        /// The service configuration associated with the resource group. For details about the syntax of a service configuration, see Service configurations for resource groups.
        public let groupConfiguration: GroupConfiguration?
        /// The resource query associated with the group. For more information about resource queries, see Create a tag-based group in Resource Groups.
        public let resourceQuery: ResourceQuery?
        /// The tags associated with the group.
        public let tags: [String: String]?

        public init(group: Group? = nil, groupConfiguration: GroupConfiguration? = nil, resourceQuery: ResourceQuery? = nil, tags: [String: String]? = nil) {
            self.group = group
            self.groupConfiguration = groupConfiguration
            self.resourceQuery = resourceQuery
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
            case groupConfiguration = "GroupConfiguration"
            case resourceQuery = "ResourceQuery"
            case tags = "Tags"
        }
    }

    public struct DeleteGroupInput: AWSEncodableShape {
        /// The name or the ARN of the resource group to delete.
        public let group: String?

        public init(group: String? = nil) {
            self.group = group
        }

        public func validate(name: String) throws {
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
        }
    }

    public struct DeleteGroupOutput: AWSDecodableShape {
        /// A full description of the deleted resource group.
        public let group: Group?

        public init(group: Group? = nil) {
            self.group = group
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
        }
    }

    public struct FailedResource: AWSDecodableShape {
        /// The error code associated with the failure.
        public let errorCode: String?
        /// The error message text associated with the failure.
        public let errorMessage: String?
        /// The ARN of the resource that failed to be added or removed.
        public let resourceArn: String?

        public init(errorCode: String? = nil, errorMessage: String? = nil, resourceArn: String? = nil) {
            self.errorCode = errorCode
            self.errorMessage = errorMessage
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: String, CodingKey {
            case errorCode = "ErrorCode"
            case errorMessage = "ErrorMessage"
            case resourceArn = "ResourceArn"
        }
    }

    public struct GetGroupConfigurationInput: AWSEncodableShape {
        /// The name or the ARN of the resource group.
        public let group: String?

        public init(group: String? = nil) {
            self.group = group
        }

        public func validate(name: String) throws {
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
        }
    }

    public struct GetGroupConfigurationOutput: AWSDecodableShape {
        /// The service configuration associated with the specified group. For details about the service configuration syntax, see Service configurations for resource groups.
        public let groupConfiguration: GroupConfiguration?

        public init(groupConfiguration: GroupConfiguration? = nil) {
            self.groupConfiguration = groupConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case groupConfiguration = "GroupConfiguration"
        }
    }

    public struct GetGroupInput: AWSEncodableShape {
        /// The name or the ARN of the resource group to retrieve.
        public let group: String?

        public init(group: String? = nil) {
            self.group = group
        }

        public func validate(name: String) throws {
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
        }
    }

    public struct GetGroupOutput: AWSDecodableShape {
        /// A full description of the resource group.
        public let group: Group?

        public init(group: Group? = nil) {
            self.group = group
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
        }
    }

    public struct GetGroupQueryInput: AWSEncodableShape {
        /// The name or the ARN of the resource group to query.
        public let group: String?

        public init(group: String? = nil) {
            self.group = group
        }

        public func validate(name: String) throws {
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
        }
    }

    public struct GetGroupQueryOutput: AWSDecodableShape {
        /// The resource query associated with the specified group. For more information about resource queries, see Create a tag-based group in Resource Groups.
        public let groupQuery: GroupQuery?

        public init(groupQuery: GroupQuery? = nil) {
            self.groupQuery = groupQuery
        }

        private enum CodingKeys: String, CodingKey {
            case groupQuery = "GroupQuery"
        }
    }

    public struct GetTagsInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "arn", location: .uri(locationName: "Arn"))
        ]

        /// The ARN of the resource group whose tags you want to retrieve.
        public let arn: String

        public init(arn: String) {
            self.arn = arn
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 1600)
            try self.validate(self.arn, name: "arn", parent: name, min: 12)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/[a-zA-Z0-9_\\.-]{1,128}")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetTagsOutput: AWSDecodableShape {
        /// The ARN of the tagged resource group.
        public let arn: String?
        /// The tags associated with the specified resource group.
        public let tags: [String: String]?

        public init(arn: String? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case tags = "Tags"
        }
    }

    public struct Group: AWSDecodableShape {
        /// The description of the resource group.
        public let description: String?
        /// The ARN of the resource group.
        public let groupArn: String
        /// The name of the resource group.
        public let name: String

        public init(description: String? = nil, groupArn: String, name: String) {
            self.description = description
            self.groupArn = groupArn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case groupArn = "GroupArn"
            case name = "Name"
        }
    }

    public struct GroupConfiguration: AWSDecodableShape {
        /// The configuration currently associated with the group and in effect.
        public let configuration: [GroupConfigurationItem]?
        /// If present, the reason why a request to update the group configuration failed.
        public let failureReason: String?
        /// If present, the new configuration that is in the process of being applied to the group.
        public let proposedConfiguration: [GroupConfigurationItem]?
        /// The current status of an attempt to update the group configuration.
        public let status: GroupConfigurationStatus?

        public init(configuration: [GroupConfigurationItem]? = nil, failureReason: String? = nil, proposedConfiguration: [GroupConfigurationItem]? = nil, status: GroupConfigurationStatus? = nil) {
            self.configuration = configuration
            self.failureReason = failureReason
            self.proposedConfiguration = proposedConfiguration
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case configuration = "Configuration"
            case failureReason = "FailureReason"
            case proposedConfiguration = "ProposedConfiguration"
            case status = "Status"
        }
    }

    public struct GroupConfigurationItem: AWSEncodableShape & AWSDecodableShape {
        /// A collection of parameters for this group configuration item. For the list of parameters that you can use with each configuration item type, see Supported resource types and parameters.
        public let parameters: [GroupConfigurationParameter]?
        /// Specifies the type of group configuration item. Each item must have a unique value for type. For the list of types that you can specify for a configuration item, see Supported resource types and parameters.
        public let type: String

        public init(parameters: [GroupConfigurationParameter]? = nil, type: String) {
            self.parameters = parameters
            self.type = type
        }

        public func validate(name: String) throws {
            try self.parameters?.forEach {
                try $0.validate(name: "\(name).parameters[]")
            }
            try self.validate(self.type, name: "type", parent: name, max: 40)
            try self.validate(self.type, name: "type", parent: name, pattern: "AWS::[a-zA-Z0-9]+::[a-zA-Z0-9]+")
        }

        private enum CodingKeys: String, CodingKey {
            case parameters = "Parameters"
            case type = "Type"
        }
    }

    public struct GroupConfigurationParameter: AWSEncodableShape & AWSDecodableShape {
        /// The name of the group configuration parameter. For the list of parameters that you can use with each configuration item type, see Supported resource types and parameters.
        public let name: String
        /// The value or values to be used for the specified parameter. For the list of values you can use with each parameter, see Supported resource types and parameters.
        public let values: [String]?

        public init(name: String, values: [String]? = nil) {
            self.name = name
            self.values = values
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 80)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "[a-z-]+")
            try self.values?.forEach {
                try validate($0, name: "values[]", parent: name, max: 256)
                try validate($0, name: "values[]", parent: name, min: 1)
                try validate($0, name: "values[]", parent: name, pattern: "[a-zA-Z0-9:_-]+")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case values = "Values"
        }
    }

    public struct GroupFilter: AWSEncodableShape {
        /// The name of the filter. Filter names are case-sensitive.
        public let name: GroupFilterName
        /// One or more filter values. Allowed filter values vary by group filter name, and are case-sensitive.
        public let values: [String]

        public init(name: GroupFilterName, values: [String]) {
            self.name = name
            self.values = values
        }

        public func validate(name: String) throws {
            try self.values.forEach {
                try validate($0, name: "values[]", parent: name, max: 128)
                try validate($0, name: "values[]", parent: name, min: 1)
                try validate($0, name: "values[]", parent: name, pattern: "AWS::(AllSupported|[a-zA-Z0-9]+::[a-zA-Z0-9]+)")
            }
            try self.validate(self.values, name: "values", parent: name, max: 5)
            try self.validate(self.values, name: "values", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case values = "Values"
        }
    }

    public struct GroupIdentifier: AWSDecodableShape {
        /// The ARN of the resource group.
        public let groupArn: String?
        /// The name of the resource group.
        public let groupName: String?

        public init(groupArn: String? = nil, groupName: String? = nil) {
            self.groupArn = groupArn
            self.groupName = groupName
        }

        private enum CodingKeys: String, CodingKey {
            case groupArn = "GroupArn"
            case groupName = "GroupName"
        }
    }

    public struct GroupQuery: AWSDecodableShape {
        /// The name of the resource group that is associated with the specified resource query.
        public let groupName: String
        /// The resource query that determines which AWS resources are members of the associated resource group.
        public let resourceQuery: ResourceQuery

        public init(groupName: String, resourceQuery: ResourceQuery) {
            self.groupName = groupName
            self.resourceQuery = resourceQuery
        }

        private enum CodingKeys: String, CodingKey {
            case groupName = "GroupName"
            case resourceQuery = "ResourceQuery"
        }
    }

    public struct GroupResourcesInput: AWSEncodableShape {
        /// The name or the ARN of the resource group to add resources to.
        public let group: String
        /// The list of ARNs for resources to be added to the group.
        public let resourceArns: [String]

        public init(group: String, resourceArns: [String]) {
            self.group = group
            self.resourceArns = resourceArns
        }

        public func validate(name: String) throws {
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
            try self.resourceArns.forEach {
                try validate($0, name: "resourceArns[]", parent: name, pattern: "arn:aws(-[a-z]+)*:[a-z0-9\\-]*:([a-z]{2}(-[a-z]+)+-\\d{1})?:([0-9]{12})?:.+")
            }
            try self.validate(self.resourceArns, name: "resourceArns", parent: name, max: 10)
            try self.validate(self.resourceArns, name: "resourceArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
            case resourceArns = "ResourceArns"
        }
    }

    public struct GroupResourcesOutput: AWSDecodableShape {
        /// A list of ARNs of any resources that failed to be added to the group by this operation.
        public let failed: [FailedResource]?
        /// A list of ARNs of any resources that are still in the process of being added to the group by this operation. These pending additions continue asynchronously. You can check the status of pending additions by using the  ListGroupResources  operation, and checking the Resources array in the response and the Status field of each object in that array.
        public let pending: [PendingResource]?
        /// A list of ARNs of resources that were successfully added to the group by this operation.
        public let succeeded: [String]?

        public init(failed: [FailedResource]? = nil, pending: [PendingResource]? = nil, succeeded: [String]? = nil) {
            self.failed = failed
            self.pending = pending
            self.succeeded = succeeded
        }

        private enum CodingKeys: String, CodingKey {
            case failed = "Failed"
            case pending = "Pending"
            case succeeded = "Succeeded"
        }
    }

    public struct ListGroupResourcesInput: AWSEncodableShape {
        /// Filters, formatted as ResourceFilter objects, that you want to apply to a ListGroupResources operation. Filters the results to include only those of the specified resource types.    resource-type - Filter resources by their type. Specify up to five resource types in the format AWS::ServiceCode::ResourceType. For example, AWS::EC2::Instance, or AWS::S3::Bucket.    When you specify a resource-type filter for ListGroupResources, AWS Resource Groups validates your filter resource types against the types that are defined in the query associated with the group. For example, if a group contains only S3 buckets because its query specifies only that resource type, but your resource-type filter includes EC2 instances, AWS Resource Groups does not filter for EC2 instances. In this case, a ListGroupResources request returns a BadRequestException error with a message similar to the following:  The resource types specified as filters in the request are not valid.  The error includes a list of resource types that failed the validation because they are not part of the query associated with the group. This validation doesn't occur when the group query specifies AWS::AllSupported, because a group based on such a query can contain any of the allowed resource types for the query type (tag-based or AWS CloudFormation stack-based queries).
        public let filters: [ResourceFilter]?
        /// The name or the ARN of the resource group
        public let group: String?
        /// The total number of results that you want included on each page of the response. If you do not include this parameter, it defaults to a value that is specific to the operation. If additional items exist beyond the maximum you specify, the NextToken response element is present and has a value (is not null). Include that value as the NextToken request parameter in the next call to the operation to get the next part of the results. Note that the service might return fewer results than the maximum even when there are more results available. You should check NextToken after every operation to ensure that you receive all of the results.
        public let maxResults: Int?
        /// The parameter for receiving additional results if you receive a NextToken response in a previous request. A NextToken response indicates that more output is available. Set this parameter to the value provided by a previous call's NextToken response to indicate where the output should continue from.
        public let nextToken: String?

        public init(filters: [ResourceFilter]? = nil, group: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filters = filters
            self.group = group
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.filters?.forEach {
                try $0.validate(name: "\(name).filters[]")
            }
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/]*={0,2}$")
        }

        private enum CodingKeys: String, CodingKey {
            case filters = "Filters"
            case group = "Group"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListGroupResourcesItem: AWSDecodableShape {
        public let identifier: ResourceIdentifier?
        /// A structure that contains the status of this resource's membership in the group.  This field is present in the response only if the group is of type AWS::EC2::HostManagement.
        public let status: ResourceStatus?

        public init(identifier: ResourceIdentifier? = nil, status: ResourceStatus? = nil) {
            self.identifier = identifier
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case identifier = "Identifier"
            case status = "Status"
        }
    }

    public struct ListGroupResourcesOutput: AWSDecodableShape {
        /// If present, indicates that more output is available than is included in the current response. Use this value in the NextToken request parameter in a subsequent call to the operation to get the next part of the output. You should repeat this until the NextToken response element comes back as null.
        public let nextToken: String?
        /// A list of QueryError objects. Each error is an object that contains ErrorCode and Message structures. Possible values for ErrorCode are CLOUDFORMATION_STACK_INACTIVE and CLOUDFORMATION_STACK_NOT_EXISTING.
        public let queryErrors: [QueryError]?
        /// An array of resources from which you can determine each resource's identity, type, and group membership status.
        public let resources: [ListGroupResourcesItem]?

        public init(nextToken: String? = nil, queryErrors: [QueryError]? = nil, resources: [ListGroupResourcesItem]? = nil) {
            self.nextToken = nextToken
            self.queryErrors = queryErrors
            self.resources = resources
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case queryErrors = "QueryErrors"
            case resources = "Resources"
        }
    }

    public struct ListGroupsInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring(locationName: "maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring(locationName: "nextToken"))
        ]

        /// Filters, formatted as GroupFilter objects, that you want to apply to a ListGroups operation.    resource-type - Filter the results to include only those of the specified resource types. Specify up to five resource types in the format AWS::ServiceCode::ResourceType . For example, AWS::EC2::Instance, or AWS::S3::Bucket.    configuration-type - Filter the results to include only those groups that have the specified configuration types attached. The current supported values are:    AWS:EC2::CapacityReservationPool     AWS:EC2::HostManagement
        public let filters: [GroupFilter]?
        /// The total number of results that you want included on each page of the response. If you do not include this parameter, it defaults to a value that is specific to the operation. If additional items exist beyond the maximum you specify, the NextToken response element is present and has a value (is not null). Include that value as the NextToken request parameter in the next call to the operation to get the next part of the results. Note that the service might return fewer results than the maximum even when there are more results available. You should check NextToken after every operation to ensure that you receive all of the results.
        public let maxResults: Int?
        /// The parameter for receiving additional results if you receive a NextToken response in a previous request. A NextToken response indicates that more output is available. Set this parameter to the value provided by a previous call's NextToken response to indicate where the output should continue from.
        public let nextToken: String?

        public init(filters: [GroupFilter]? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.filters = filters
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.filters?.forEach {
                try $0.validate(name: "\(name).filters[]")
            }
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/]*={0,2}$")
        }

        private enum CodingKeys: String, CodingKey {
            case filters = "Filters"
        }
    }

    public struct ListGroupsOutput: AWSDecodableShape {
        /// A list of GroupIdentifier objects. Each identifier is an object that contains both the Name and the GroupArn.
        public let groupIdentifiers: [GroupIdentifier]?
        /// If present, indicates that more output is available than is included in the current response. Use this value in the NextToken request parameter in a subsequent call to the operation to get the next part of the output. You should repeat this until the NextToken response element comes back as null.
        public let nextToken: String?

        public init(groupIdentifiers: [GroupIdentifier]? = nil, nextToken: String? = nil) {
            self.groupIdentifiers = groupIdentifiers
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case groupIdentifiers = "GroupIdentifiers"
            case nextToken = "NextToken"
        }
    }

    public struct PendingResource: AWSDecodableShape {
        /// The Amazon resource name (ARN) of the resource that's in a pending state.
        public let resourceArn: String?

        public init(resourceArn: String? = nil) {
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct PutGroupConfigurationInput: AWSEncodableShape {
        /// The new configuration to associate with the specified group. A configuration associates the resource group with an AWS service and specifies how the service can interact with the resources in the group. A configuration is an array of GroupConfigurationItem elements. For information about the syntax of a service configuration, see Service configurations for resource groups.  A resource group can contain either a Configuration or a ResourceQuery, but not both.
        public let configuration: [GroupConfigurationItem]?
        /// The name or ARN of the resource group with the configuration that you want to update.
        public let group: String?

        public init(configuration: [GroupConfigurationItem]? = nil, group: String? = nil) {
            self.configuration = configuration
            self.group = group
        }

        public func validate(name: String) throws {
            try self.configuration?.forEach {
                try $0.validate(name: "\(name).configuration[]")
            }
            try self.validate(self.configuration, name: "configuration", parent: name, max: 2)
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
        }

        private enum CodingKeys: String, CodingKey {
            case configuration = "Configuration"
            case group = "Group"
        }
    }

    public struct PutGroupConfigurationOutput: AWSDecodableShape {
        public init() {}
    }

    public struct QueryError: AWSDecodableShape {
        /// Possible values are CLOUDFORMATION_STACK_INACTIVE and CLOUDFORMATION_STACK_NOT_EXISTING.
        public let errorCode: QueryErrorCode?
        /// A message that explains the ErrorCode value. Messages might state that the specified CloudFormation stack does not exist (or no longer exists). For CLOUDFORMATION_STACK_INACTIVE, the message typically states that the CloudFormation stack has a status that is not (or no longer) active, such as CREATE_FAILED.
        public let message: String?

        public init(errorCode: QueryErrorCode? = nil, message: String? = nil) {
            self.errorCode = errorCode
            self.message = message
        }

        private enum CodingKeys: String, CodingKey {
            case errorCode = "ErrorCode"
            case message = "Message"
        }
    }

    public struct ResourceFilter: AWSEncodableShape {
        /// The name of the filter. Filter names are case-sensitive.
        public let name: ResourceFilterName
        /// One or more filter values. Allowed filter values vary by resource filter name, and are case-sensitive.
        public let values: [String]

        public init(name: ResourceFilterName, values: [String]) {
            self.name = name
            self.values = values
        }

        public func validate(name: String) throws {
            try self.values.forEach {
                try validate($0, name: "values[]", parent: name, max: 128)
                try validate($0, name: "values[]", parent: name, min: 1)
                try validate($0, name: "values[]", parent: name, pattern: "AWS::[a-zA-Z0-9]+::[a-zA-Z0-9]+")
            }
            try self.validate(self.values, name: "values", parent: name, max: 5)
            try self.validate(self.values, name: "values", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case values = "Values"
        }
    }

    public struct ResourceIdentifier: AWSDecodableShape {
        /// The ARN of a resource.
        public let resourceArn: String?
        /// The resource type of a resource, such as AWS::EC2::Instance.
        public let resourceType: String?

        public init(resourceArn: String? = nil, resourceType: String? = nil) {
            self.resourceArn = resourceArn
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case resourceType = "ResourceType"
        }
    }

    public struct ResourceQuery: AWSEncodableShape & AWSDecodableShape {
        /// The query that defines a group or a search.
        public let query: String
        /// The type of the query. You can use the following values:     CLOUDFORMATION_STACK_1_0: Specifies that the Query contains an ARN for a CloudFormation stack.     TAG_FILTERS_1_0: Specifies that the Query parameter contains a JSON string that represents a collection of simple tag filters for resource types and tags. The JSON string uses a syntax similar to the  GetResources  operation, but uses only the   ResourceTypeFilters  and  TagFilters  fields. If you specify more than one tag key, only resources that match all tag keys, and at least one value of each specified tag key, are returned in your query. If you specify more than one value for a tag key, a resource matches the filter if it has a tag key value that matches any of the specified values. For example, consider the following sample query for resources that have two tags, Stage and Version, with two values each:  [{"Stage":["Test","Deploy"]},{"Version":["1","2"]}]  The results of this query could include the following.   An EC2 instance that has the following two tags: {"Stage":"Deploy"}, and {"Version":"2"}    An S3 bucket that has the following two tags: {"Stage":"Test"}, and {"Version":"1"}    The query would not include the following items in the results, however.    An EC2 instance that has only the following tag: {"Stage":"Deploy"}. The instance does not have all of the tag keys specified in the filter, so it is excluded from the results.   An RDS database that has the following two tags: {"Stage":"Archived"} and {"Version":"4"}  The database has all of the tag keys, but none of those keys has an associated value that matches at least one of the specified values in the filter.
        public let type: QueryType

        public init(query: String, type: QueryType) {
            self.query = query
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.query, name: "query", parent: name, max: 4096)
            try self.validate(self.query, name: "query", parent: name, pattern: "[\\s\\S]*")
        }

        private enum CodingKeys: String, CodingKey {
            case query = "Query"
            case type = "Type"
        }
    }

    public struct ResourceStatus: AWSDecodableShape {
        /// The current status.
        public let name: ResourceStatusValue?

        public init(name: ResourceStatusValue? = nil) {
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
        }
    }

    public struct SearchResourcesInput: AWSEncodableShape {
        /// The total number of results that you want included on each page of the response. If you do not include this parameter, it defaults to a value that is specific to the operation. If additional items exist beyond the maximum you specify, the NextToken response element is present and has a value (is not null). Include that value as the NextToken request parameter in the next call to the operation to get the next part of the results. Note that the service might return fewer results than the maximum even when there are more results available. You should check NextToken after every operation to ensure that you receive all of the results.
        public let maxResults: Int?
        /// The parameter for receiving additional results if you receive a NextToken response in a previous request. A NextToken response indicates that more output is available. Set this parameter to the value provided by a previous call's NextToken response to indicate where the output should continue from.
        public let nextToken: String?
        /// The search query, using the same formats that are supported for resource group definition. For more information, see CreateGroup.
        public let resourceQuery: ResourceQuery

        public init(maxResults: Int? = nil, nextToken: String? = nil, resourceQuery: ResourceQuery) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.resourceQuery = resourceQuery
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[a-zA-Z0-9+/]*={0,2}$")
            try self.resourceQuery.validate(name: "\(name).resourceQuery")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case resourceQuery = "ResourceQuery"
        }
    }

    public struct SearchResourcesOutput: AWSDecodableShape {
        /// If present, indicates that more output is available than is included in the current response. Use this value in the NextToken request parameter in a subsequent call to the operation to get the next part of the output. You should repeat this until the NextToken response element comes back as null.
        public let nextToken: String?
        /// A list of QueryError objects. Each error is an object that contains ErrorCode and Message structures. Possible values for ErrorCode are CLOUDFORMATION_STACK_INACTIVE and CLOUDFORMATION_STACK_NOT_EXISTING.
        public let queryErrors: [QueryError]?
        /// The ARNs and resource types of resources that are members of the group that you specified.
        public let resourceIdentifiers: [ResourceIdentifier]?

        public init(nextToken: String? = nil, queryErrors: [QueryError]? = nil, resourceIdentifiers: [ResourceIdentifier]? = nil) {
            self.nextToken = nextToken
            self.queryErrors = queryErrors
            self.resourceIdentifiers = resourceIdentifiers
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case queryErrors = "QueryErrors"
            case resourceIdentifiers = "ResourceIdentifiers"
        }
    }

    public struct TagInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "arn", location: .uri(locationName: "Arn"))
        ]

        /// The ARN of the resource group to which to add tags.
        public let arn: String
        /// The tags to add to the specified resource group. A tag is a string-to-string map of key-value pairs.
        public let tags: [String: String]

        public init(arn: String, tags: [String: String]) {
            self.arn = arn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 1600)
            try self.validate(self.arn, name: "arn", parent: name, min: 12)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/[a-zA-Z0-9_\\.-]{1,128}")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 0)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct TagOutput: AWSDecodableShape {
        /// The ARN of the tagged resource.
        public let arn: String?
        /// The tags that have been added to the specified resource group.
        public let tags: [String: String]?

        public init(arn: String? = nil, tags: [String: String]? = nil) {
            self.arn = arn
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case tags = "Tags"
        }
    }

    public struct UngroupResourcesInput: AWSEncodableShape {
        /// The name or the ARN of the resource group from which to remove the resources.
        public let group: String
        /// The ARNs of the resources to be removed from the group.
        public let resourceArns: [String]

        public init(group: String, resourceArns: [String]) {
            self.group = group
            self.resourceArns = resourceArns
        }

        public func validate(name: String) throws {
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
            try self.resourceArns.forEach {
                try validate($0, name: "resourceArns[]", parent: name, pattern: "arn:aws(-[a-z]+)*:[a-z0-9\\-]*:([a-z]{2}(-[a-z]+)+-\\d{1})?:([0-9]{12})?:.+")
            }
            try self.validate(self.resourceArns, name: "resourceArns", parent: name, max: 10)
            try self.validate(self.resourceArns, name: "resourceArns", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
            case resourceArns = "ResourceArns"
        }
    }

    public struct UngroupResourcesOutput: AWSDecodableShape {
        /// A list of any resources that failed to be removed from the group by this operation.
        public let failed: [FailedResource]?
        /// A list of any resources that are still in the process of being removed from the group by this operation. These pending removals continue asynchronously. You can check the status of pending removals by using the  ListGroupResources  operation. After the resource is successfully removed, it no longer appears in the response.
        public let pending: [PendingResource]?
        /// A list of resources that were successfully removed from the group by this operation.
        public let succeeded: [String]?

        public init(failed: [FailedResource]? = nil, pending: [PendingResource]? = nil, succeeded: [String]? = nil) {
            self.failed = failed
            self.pending = pending
            self.succeeded = succeeded
        }

        private enum CodingKeys: String, CodingKey {
            case failed = "Failed"
            case pending = "Pending"
            case succeeded = "Succeeded"
        }
    }

    public struct UntagInput: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "arn", location: .uri(locationName: "Arn"))
        ]

        /// The ARN of the resource group from which to remove tags. The command removed both the specified keys and any values associated with those keys.
        public let arn: String
        /// The keys of the tags to be removed.
        public let keys: [String]

        public init(arn: String, keys: [String]) {
            self.arn = arn
            self.keys = keys
        }

        public func validate(name: String) throws {
            try self.validate(self.arn, name: "arn", parent: name, max: 1600)
            try self.validate(self.arn, name: "arn", parent: name, min: 12)
            try self.validate(self.arn, name: "arn", parent: name, pattern: "arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/[a-zA-Z0-9_\\.-]{1,128}")
            try self.keys.forEach {
                try validate($0, name: "keys[]", parent: name, max: 128)
                try validate($0, name: "keys[]", parent: name, min: 1)
                try validate($0, name: "keys[]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case keys = "Keys"
        }
    }

    public struct UntagOutput: AWSDecodableShape {
        /// The ARN of the resource group from which tags have been removed.
        public let arn: String?
        /// The keys of the tags that were removed.
        public let keys: [String]?

        public init(arn: String? = nil, keys: [String]? = nil) {
            self.arn = arn
            self.keys = keys
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case keys = "Keys"
        }
    }

    public struct UpdateGroupInput: AWSEncodableShape {
        /// The new description that you want to update the resource group with. Descriptions can contain letters, numbers, hyphens, underscores, periods, and spaces.
        public let description: String?
        /// The name or the ARN of the resource group to modify.
        public let group: String?

        public init(description: String? = nil, group: String? = nil) {
            self.description = description
            self.group = group
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "[\\sa-zA-Z0-9_\\.-]*")
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case group = "Group"
        }
    }

    public struct UpdateGroupOutput: AWSDecodableShape {
        /// The update description of the resource group.
        public let group: Group?

        public init(group: Group? = nil) {
            self.group = group
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
        }
    }

    public struct UpdateGroupQueryInput: AWSEncodableShape {
        /// The name or the ARN of the resource group to query.
        public let group: String?
        /// The resource query to determine which AWS resources are members of this resource group.  A resource group can contain either a Configuration or a ResourceQuery, but not both.
        public let resourceQuery: ResourceQuery

        public init(group: String? = nil, resourceQuery: ResourceQuery) {
            self.group = group
            self.resourceQuery = resourceQuery
        }

        public func validate(name: String) throws {
            try self.validate(self.group, name: "group", parent: name, max: 1600)
            try self.validate(self.group, name: "group", parent: name, min: 1)
            try self.validate(self.group, name: "group", parent: name, pattern: "(arn:aws(-[a-z]+)*:resource-groups:[a-z]{2}(-[a-z]+)+-\\d{1}:[0-9]{12}:group/)?[a-zA-Z0-9_\\.-]{1,128}")
            try self.resourceQuery.validate(name: "\(name).resourceQuery")
        }

        private enum CodingKeys: String, CodingKey {
            case group = "Group"
            case resourceQuery = "ResourceQuery"
        }
    }

    public struct UpdateGroupQueryOutput: AWSDecodableShape {
        /// The updated resource query associated with the resource group after the update.
        public let groupQuery: GroupQuery?

        public init(groupQuery: GroupQuery? = nil) {
            self.groupQuery = groupQuery
        }

        private enum CodingKeys: String, CodingKey {
            case groupQuery = "GroupQuery"
        }
    }
}
